from django.contrib.auth.hashers import make_password,check_password
from django.shortcuts import render,redirect,reverse
from django.utils.decorators import method_decorator
from django.views import View
from .models import Teachers,Subjects,ExamExtension,Exam,ExamPaper,StudentsAnswer
from .form import Changepass,Teacher_add,Add_student,SetExam,SetExamObject,ReleaseExamForm
from django.contrib import messages
import csv,codecs
from django.http import HttpResponse
from io import StringIO
from student_front.models import Students
from datetime import datetime
from pytz import timezone
from teacher_front.teacher_decorator import check_login

@method_decorator(check_login,name='dispatch')
class Teacher_dashbord(View):
    def get(self,request):
        teacher_num = request.session.get('user_id')
        subjects = Subjects.objects.values('name').distinct()
        infos = []
        for subject in subjects:
            info_factor = {}
            exist = Subjects.objects.filter(name=subject['name'],teacher__number=teacher_num)
            if exist:
                num = Subjects.objects.filter(name=subject['name'],teacher__number=teacher_num).count()
                time = Subjects.objects.filter(name=subject['name'],teacher__number=teacher_num).first().creat_time
                course_id = Subjects.objects.filter(name=subject['name'],teacher__number=teacher_num).first().id
                info_factor['name'] = subject['name']
                info_factor['time'] = time
                info_factor['num'] = num
                info_factor['course_id'] = course_id
                info_factor['exam_set'] = Subjects.objects.filter(name=subject['name'],teacher__number=teacher_num).first().exam_set
                if info_factor['exam_set']:
                    info_factor['start_time'] = Subjects.objects.filter(name=subject['name'],teacher__number=teacher_num).first().exam.start_time
                    info_factor['end_time'] = Subjects.objects.filter(name=subject['name'],teacher__number=teacher_num).first().exam.end_time
                    info_factor['time_limit'] = Subjects.objects.filter(name=subject['name'],teacher__number=teacher_num).first().exam.time_limit
                infos.append(info_factor)
            else:
                continue
        context = {'infos':infos}
        return render(request,'teacher_dashbord.html',context=context)

def logout(request):
    request.session.clear()
    return redirect(reverse('index'))

@method_decorator(check_login,name='dispatch')
class Change_password(View):
    def get(self,request):
        return render(request,'teacher_changepassword.html')
    def post(self,request):
        teacher_id = request.session.get('user_id')
        teacher = Teachers.objects.filter(number=teacher_id).first()
        form = Changepass(request.POST)
        if form.is_valid():
            new_password = form.cleaned_data.get('new_password')
            password = form.cleaned_data.get('password')
            real_password = teacher.password
            if check_password(password,real_password):
                teacher.password = make_password(new_password)
                teacher.save()
                return redirect(reverse('teacher:dashbord'))
            else:
                messages.info(request,'原密码不正确！')
        else:
            erros = form.get_error()
            for erro in erros:
                messages.info(request, erro)
                return redirect(reverse('teacher:changepass'))

def downloadcsv(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="sample.csv"'
    response.write(codecs.BOM_UTF8)
    writer = csv.writer(response)
    writer.writerow(['学号', '姓名'])
    writer.writerow(['201731053326', '潘芸芃'])
    return response

@method_decorator(check_login,name='dispatch')
class Add_course(View):
    def get(self,request):
        return render(request,'teacher_addcourse.html')
    def post(self,request):
        teacher_id = request.session.get('user_id')
        teacher = Teachers.objects.filter(number=teacher_id).first()
        form = Teacher_add(request.POST,request.FILES)
        if form.is_valid():
            name = form.cleaned_data.get('course_name')
            students = request.FILES.get('my_file')
            file = students.read().decode('utf-8')
            csv_data = csv.reader(StringIO(file), delimiter=',')
            next(csv_data)
            for row in csv_data:
                try:
                    student_number = row[0].replace(' ','')
                    student_name = row[1]
                    exist = Students.objects.filter(number=student_number).exists()
                    if exist:
                        student = Students.objects.filter(number=student_number).first()
                        subject = Subjects(name=name,teacher=teacher,student=student)
                        subject.save()
                    else:
                        student_pass = make_password(student_number[-6:])
                        new_student = Students(number=student_number,name=student_name,password=student_pass)
                        new_student.save()
                        subject = Subjects(name=name,teacher=teacher,student=new_student)
                        subject.save()
                except:
                    continue
            return redirect(reverse('teacher:dashbord'))
        else:
            erros = form.get_error()
            for erro in erros:
                messages.info(request, erro)
                return redirect(reverse('teacher:addcourse'))

@method_decorator(check_login,name='dispatch')
class Manage_course(View):
    def get(self,request,course_id):
        course = Subjects.objects.filter(pk=course_id).first()
        teacher = Teachers.objects.filter(pk=request.session.get('user_id')).first()
        students = Students.objects.filter(subjects__name=course.name,subjects__teacher__name=course.teacher.name).all()
        studentsinfos = []
        for student in students:
            studentsinfo = {}
            studentsinfo['number'] = student.number
            studentsinfo['name'] = student.name
            if Exam.objects.filter(subject__student=student,subject__teacher=teacher,subject__name=course.name).exists():
                exam = Exam.objects.filter(subject__student=student,subject__teacher=teacher,subject__name=course.name).first()
                studentsinfo['inputPaper'] = exam.state
                studentsinfo['total_score'] = exam.total_score
            studentsinfos.append(studentsinfo)
        context = {
            'students': studentsinfos,
            'course': course.name,
            'teacher': teacher.name,
        }
        return render(request,'manage_course.html',context=context)

@check_login
def del_course_stu(request,name,num):
    teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
    subject = Subjects.objects.filter(teacher=teacher,student__number=num,name=name)
    subject.delete()
    subject1 = Subjects.objects.filter(teacher=teacher,name=name).first()
    return redirect(reverse('teacher:managecourse',kwargs={'course_id':subject1.id}))

@check_login
def del_cor(request, teacher_name, course_course):
    subjects = Subjects.objects.filter(name=course_course,teacher__name=teacher_name)
    subjects.delete()
    return redirect(reverse('teacher:dashbord'))

@method_decorator(check_login,name='dispatch')
class Add_stu(View):
    def get(self,request):
        return render(request,'teacher_add_stu.html')
    def post(self,request):
        form = Add_student(request.POST)
        course_name = request.GET.get('course')
        if form.is_valid():
            stu_num = form.cleaned_data.get('student_number')
            stu_name = form.cleaned_data.get(('student_name'))
            teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
            exist = Students.objects.filter(number=stu_num).exists()
            if exist:
                student = Students.objects.filter(number=stu_num).first()
                subject = Subjects(name=course_name, teacher=teacher, student=student)
                subject.save()
                return redirect(reverse('teacher:managecourse',kwargs={'course_id':subject.id}))
            else:
                student_pass = make_password(stu_num[-6:])
                new_student = Students(number=stu_num, name=stu_name, password=student_pass)
                new_student.save()
                subject = Subjects(name=course_name, teacher=teacher, student=new_student)
                subject.save()
        else:
            erros = form.get_error()
            for erro in erros:
                messages.info(request,erro)
            return redirect(reverse('teacher:addstu')+ f"?course={course_name }")

@method_decorator(check_login,name='dispatch')
class Set_exampaper(View):

    def get(self,request):
        teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
        course = request.GET.get('course')
        questions_single = ExamExtension.objects.filter(exam__name=course,exam__teacher=teacher,type='single').all()
        questions_multiple = ExamExtension.objects.filter(exam__name=course,exam__teacher=teacher,type='multiple').all()
        questions_subjective = ExamExtension.objects.filter(exam__name=course,exam__teacher=teacher,type='subjective').all()
        context = {
            'course':course,
            'questions_single':questions_single,
            'questions_multiple':questions_multiple,
            'questions_subjective':questions_subjective
        }
        return render(request,'teacher_setexam.html',context=context)

@method_decorator(check_login,name='dispatch')
class Add_question(View):
    def get(self,request):
        teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
        course = request.GET.get('course')
        questions_single = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher, type='single').all()
        questions_multiple = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher,
                                                          type='multiple').all()
        questions_subjective = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher,
                                                            type='subjective').all()

        if request.GET.get('type') == 'subjective':
            form = SetExam()
            return render(request,'setsubjectiveque.html',{'form':form,'questions_single':questions_single,'questions_multiple':questions_multiple,'questions_subjective':questions_subjective,'course':course})
        elif request.GET.get('type') == 'single':
            form = SetExamObject()
            return render(request,'setsingleque.html',{'form':form,'questions_single':questions_single,'questions_multiple':questions_multiple,'questions_subjective':questions_subjective,'course':course})
        else:
            form = SetExamObject()
            return render(request, 'setmultipleque.html', {'form': form,'questions_single':questions_single,'questions_multiple':questions_multiple,'questions_subjective':questions_subjective,'course':course})
    def post(self,request):
        if request.GET.get('type') == 'subjective':
            teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
            course = request.GET.get('course')
            if ExamPaper.objects.filter(name=course,teacher=teacher).exists():
                exampapaer = ExamPaper.objects.filter(name=course,teacher=teacher).first()
                form = SetExam(request.POST)
                if form.is_valid():
                    question = form.cleaned_data.get('question')
                    type = request.GET.get('type')
                    value = form.cleaned_data.get('value')
                    examextension = ExamExtension.objects.create(question=question,type=type,value=value,exam=exampapaer)
                    return redirect(reverse('teacher:setexampaper')+f"?course={course}")

            else:
                exampaper = ExamPaper.objects.create(name=course,teacher=teacher)
                form = SetExam(request.POST)
                if form.is_valid():
                    question = form.cleaned_data.get('question')
                    type = request.GET.get('type')
                    value = form.cleaned_data.get('value')
                    examextension = ExamExtension.objects.create(question=question,type=type,value=value,exam=exampaper)
                    return redirect(reverse('teacher:setexampaper') + f"?course={course}")

        elif request.GET.get('type') == 'single':
            teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
            course = request.GET.get('course')
            if ExamPaper.objects.filter(name=course, teacher=teacher).exists():
                exampapaer = ExamPaper.objects.filter(name=course, teacher=teacher).first()
                form = SetExam(request.POST)
                if form.is_valid():
                    question = form.cleaned_data.get('question')
                    type = request.GET.get('type')
                    value = form.cleaned_data.get('value')
                    answer = request.POST.get('answer').replace('','')
                    print(answer)
                    examextension = ExamExtension.objects.create(question=question, type=type, value=value,answer=answer,
                                                                 exam=exampapaer)
                    return redirect(reverse('teacher:setexampaper') + f"?course={course}")

            else:
                exampaper = ExamPaper.objects.create(name=course, teacher=teacher)
                form = SetExam(request.POST)
                if form.is_valid():
                    question = form.cleaned_data.get('question')
                    type = request.GET.get('type')
                    value = form.cleaned_data.get('value')
                    answer = request.POST.get('answer').replace('','')
                    examextension = ExamExtension.objects.create(question=question, type=type, value=value,answer=answer,
                                                                 exam=exampaper)
                    return redirect(reverse('teacher:setexampaper') + f"?course={course}")
        else:
            teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
            course = request.GET.get('course')
            if ExamPaper.objects.filter(name=course, teacher=teacher).exists():
                exampapaer = ExamPaper.objects.filter(name=course, teacher=teacher).first()
                form = SetExam(request.POST)
                if form.is_valid():
                    question = form.cleaned_data.get('question')
                    type = request.GET.get('type')
                    value = form.cleaned_data.get('value')
                    answer = request.POST.get('answer').replace('','')
                    examextension = ExamExtension.objects.create(question=question, type=type, value=value,
                                                                 answer=answer,
                                                                 exam=exampapaer)
                    return redirect(reverse('teacher:setexampaper') + f"?course={course}")

            else:
                exampaper = ExamPaper.objects.create(name=course, teacher=teacher)
                form = SetExam(request.POST)
                if form.is_valid():
                    question = form.cleaned_data.get('question')
                    type = request.GET.get('type')
                    value = form.cleaned_data.get('value')
                    answer = request.POST.get('answer').replace('','')
                    examextension = ExamExtension.objects.create(question=question, type=type, value=value,
                                                                 answer=answer,
                                                                 exam=exampaper)
                    return redirect(reverse('teacher:setexampaper') + f"?course={course}")

@method_decorator(check_login,name='dispatch')
class ModifyQuestion(View):
    def get(self,request):
        teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
        course = request.GET.get('course')
        questions_single = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher, type='single').all()
        questions_multiple = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher,
                                                          type='multiple').all()
        questions_subjective = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher,
                                                            type='subjective').all()
        id = request.GET.get('id')
        que = ExamExtension.objects.filter(pk=id).first()
        if request.GET.get('type') == 'subjective':
            form = SetExam(instance=que)
            return render(request,'modifyque.html',{'form':form,'questions_single':questions_single,'questions_multiple':questions_multiple,'questions_subjective':questions_subjective,'course':course,'qid':id})
        else:
            form = SetExamObject(instance=que)
            return render(request, 'modifyque.html', {'form': form, 'questions_single':questions_single,'questions_multiple':questions_multiple,'questions_subjective':questions_subjective, 'course': course,'qid':id})
    def post(self,request):
        course = request.GET.get('course')
        id = request.GET.get('id')
        que = ExamExtension.objects.filter(pk=id).first()
        if request.GET.get('type') == 'subjective':
            form = SetExam(request.POST,instance=que)
            if form.is_valid():
                form.save()
                return redirect(reverse('teacher:setexampaper')+f'?course={course}')
        else:
            form = SetExamObject(request.POST,instance=que)
            if form.is_valid():
                form.save()
                return redirect(reverse('teacher:setexampaper')+f'?course={course}')

@check_login
def delque(request):
    course = request.GET.get('course')
    id = request.GET.get('id')
    que = ExamExtension.objects.filter(pk=id).first()
    que.delete()
    return redirect(reverse('teacher:setexampaper') + f'?course={course}')

@method_decorator(check_login,name='dispatch')
class ReleaseExam(View):
    def get(self,request):
        teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
        course = request.GET.get('course')
        questions_single = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher, type='single').all()
        questions_multiple = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher,
                                                          type='multiple').all()
        questions_subjective = ExamExtension.objects.filter(exam__name=course, exam__teacher=teacher,
                                                            type='subjective').all()
        return render(request, 'release.html',
                      {'questions_single': questions_single, 'questions_multiple': questions_multiple,
                       'questions_subjective': questions_subjective, 'course': course,})
    def post(self,request):
        teacher = Teachers.objects.filter(number=request.session.get('user_id')).first()
        course = request.GET.get('course')
        form = ReleaseExamForm(request.POST)
        if form.is_valid():
            time_str = form.cleaned_data.get('start_time')
            time_str = time_str.split(' / ')
            start_time = datetime.strptime(time_str[0],'%Y-%m-%d %H:%M')
            end_time = datetime.strptime(time_str[1],'%Y-%m-%d %H:%M')
            cst_tz = timezone('Asia/Shanghai')
            start_time1 = start_time.replace(tzinfo=cst_tz)
            end_time1 = end_time.replace(tzinfo=cst_tz)
            time_limit = form.cleaned_data.get('limit_time')
            subjects = Subjects.objects.filter(name=course,teacher=teacher).all()
            exampaper = ExamPaper.objects.filter(name=course,teacher=teacher).first()
            for subject in subjects:
                if Exam.objects.filter(subject=subject).exists():
                    exam = Exam.objects.filter(subject=subject).first()
                    exam.start_time = start_time1
                    exam.end_time = end_time1
                    exam.time_limit = time_limit
                    exam.save()
                else:
                    exam = Exam.objects.create(state=True,name=course,start_time=start_time1,end_time=end_time1,time_limit=time_limit,subject=subject,exampaper=exampaper)
                    subject.exam_set = True
                    subject.save()
            return redirect(reverse('teacher:dashbord'))
        else:
            erros = form.get_error()
            print(erros)
            for erro in erros:
                messages.info(request, erro)
                return redirect(reverse('teacher:release')+f'?courese={course}')

@method_decorator(check_login,name='dispatch')
class MarkPaper(View):
    def get(self,request,stu_id):
        subject = Subjects.objects.filter(student__number=stu_id).first()
        examquestions = ExamExtension.objects.filter(exam__exam__subject=subject).all()
        paperinfos = []
        for examquestion in examquestions:
            paperinfo = {}
            paperinfo['question'] = examquestion.question
            answer = StudentsAnswer.objects.filter(examextension=examquestion,subject=subject)
            if answer.exists():
                paperinfo['answer'] = StudentsAnswer.objects.filter(examextension=examquestion,subject=subject).first().ans
                paperinfo['score'] = StudentsAnswer.objects.filter(examextension=examquestion,subject=subject).first().total_score
            else:
                paperinfo['answer'] = ' '
                paperinfo['score'] = '0'
            paperinfo['que_id'] = examquestion.id
            paperinfos.append(paperinfo)
        return render(request,'teacher_mark.html',{'paperinfos':paperinfos})
    def post(self,request,stu_id):
        subject = Subjects.objects.filter(student__number=stu_id).first()
        examquestions = ExamExtension.objects.filter(exam__exam__subject=subject).all()
        total = 0
        for examquestion in examquestions:
            qid = examquestion.id
            score = request.POST.get(str(qid))
            if StudentsAnswer.objects.filter(examextension=examquestion, subject=subject).exists():
                que_score = StudentsAnswer.objects.filter(examextension=examquestion, subject=subject).first()
                que_score.total_score = score
                que_score.save()
            total = total + int(score)
        exam = Exam.objects.filter(subject=subject).first()
        exam.total_score = total
        exam.save()
        return redirect(reverse('teacher:managecourse', args=[subject.id]))

@check_login
def downloadStuScore(request):
    teacher = Teachers.objects.filter(pk=request.session.get('user_id')).first()
    course_name = request.GET.get('course_name')
    exams = Exam.objects.filter(exampaper__teacher=teacher,subject__name=course_name).all()
    response = HttpResponse(content_type='text/csv')
    response.write(codecs.BOM_UTF8)
    response['Content-Disposition'] = 'attachment; filename="score.csv"'
    writer = csv.writer(response)
    writer.writerow(['学号', '姓名','成绩'])
    for exam in exams:
        writer.writerow([exam.subject.student.number, exam.subject.student.name, exam.total_score])
    return response